#include "snake.h"
#include "ui_snake.h"
#include<qtimer.h>
#include<QKeyEvent>
#include<QRandomGenerator>

Snake::Snake(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Snake),blsRun(false),speed(500)
{
    ui->setupUi(this);
    this->setGeometry(QRect(600,300,290,310));
}

Snake::~Snake()
{
    delete ui;
}
void Snake::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    if(!blsRun)
    {
        InitSnake();//初始化蛇，此时蛇没有画，只是初始化了矩形
    }
    //画游戏背景
    //外墙
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::gray);//设置填充颜色
    painter.drawRect(15,15,260,260);//画矩形，相对于窗体的起点坐标（15,25），大小为260*260
    //内墙
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::white);//设置填充颜色
    painter.drawPixmap(20,20,250,250,QPixmap(":/mag/toilet.jpg"));//画矩形，相对于窗体的起点坐标（20,20），大小为250*250
    //花小格子，大小10*10
    /*painter.setPen(Qt::blue);//设置画笔颜色
    for(int i=0;i<=27;i++)
    {
        painter.drawLine(20,i*10,270,i*10);//画横线
        painter.drawLine(i*10,20,i*10,270);//画竖线
    }*/
    //显示游戏开始，结束
    QFont font1("Courier",24);
    painter.setFont(font1);
    painter.setPen(Qt::red);
    painter.setBrush(Qt::red);
    painter.drawText(40,150,sDisplay);
    //得分显示
    QFont font2("Courier",15);
    painter.setFont(font2);
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::blue);
    painter.drawText(140,300,scoreLabel);
    painter.drawText(230,300,QString::number(nScore));
    //画蛇
    painter.setPen(Qt::black);//设置画笔颜色
    painter.setBrush(Qt::black);//设置填充颜色
    painter.drawPixmap(food,QPixmap(":/mag/shit.jpg"));
    painter.drawRects(&vSnakeRect[0],vSnakeRect.size());//画n个小方块
    painter.drawPixmap(vSnakeRect[0],QPixmap(":/mag/dog.jpg"));
    if(blsOver)//游戏结束，停止计时器
        timer->stop();
}
QRect Snake::CreateRect()
{
    int x,y;
    x=QRandomGenerator::global()->bounded(0,1000)%25;//生成小于25的整数
    y=QRandomGenerator::global()->bounded(0,1000)%25;
    QRect rect(20+x*10,20+y*10,10,10);//食物小方块的位置
    return rect;
}
void Snake::InitSnake()
{
    nDirection=2;//默认向下移动
    blsRun=true;
    blsOver=false;
    sDisplay="游戏开始";
    scoreLabel="得分";
    nScore=0;
    food=CreateRect();//创建食物
    vSnakeRect.resize(5);//初始化snake的长度是5
    for(int i=0;i<vSnakeRect.size();i++)//初始化vector
    {
        QRect rect(100,70+10*i,10,10);//生成小方块
        vSnakeRect[vSnakeRect.size()-1-i]=rect;//小方块赋值到容器
    }
    SnakeHead=vSnakeRect.first();//指定蛇头位置
    timer=new QTimer(this);//设置计时器
    timer->start(speed);//计时器时间为1s
    connect(timer,SIGNAL(timeout()),SLOT(Snake_update()));//信号连接槽，发出信号的是timer，信号是timeout，执行的槽是Snake_update
}
void Snake::keyPressEvent(QKeyEvent *event)
{
    QKeyEvent *key=(QKeyEvent*)event;
    switch (key->key())
    {
    case Qt::Key_Up:nDirection=1;//1是上
        break;
    case Qt::Key_Down:nDirection=2;//2是下
        break;
    case Qt::Key_Left:nDirection=3;//3是左
        break;
    case Qt::Key_Right:nDirection=4;//4是右
        break;
    default:;
    }
}
void Snake::Snake_update()
{
    sDisplay="";
    SnakeHead=vSnakeRect.first();//获取到蛇头
    IsEat();
    IsHit();
    for(int j=0;j<vSnakeRect.size()-1;j++)
    {
        vSnakeRect[vSnakeRect.size()-1-j]=vSnakeRect[vSnakeRect.size()-2-j];
    }
    switch(nDirection)
    {
    case 1:
        SnakeHead.setTop(SnakeHead.top()-10);
        SnakeHead.setBottom(SnakeHead.bottom()-10);
        break;
    case 2:
        SnakeHead.setTop(SnakeHead.top()+10);
        SnakeHead.setBottom(SnakeHead.bottom()+10);
        break;
    case 3:
        SnakeHead.setLeft(SnakeHead.left()-10);
        SnakeHead.setRight(SnakeHead.right()-10);
        break;
    case 4:
        SnakeHead.setLeft(SnakeHead.left()+10);
        SnakeHead.setRight(SnakeHead.right()+10);
        break;
    default:;
    }
    vSnakeRect[0]=SnakeHead;//第一个节点为蛇头位置
    if(SnakeHead.left()<20||SnakeHead.right()>270||SnakeHead.top()<20||SnakeHead.bottom()>270)
    {
        sDisplay="游戏结束";
        blsOver=true;
    }
    update();//paintEvent更新
}
void Snake::IsEat()
{
    if(SnakeHead==food)//蛇头和食物重合
    {
        SnakeHead=food;//吃到食物，食物变成蛇头
        vSnakeRect.push_back(vSnakeRect.last());//最后一个节点再次加到容器里，让蛇头变长
        food=CreateRect();//吃到食物再生成一个食物
        nScore+=10;//吃到食物得分
        if(speed>50)
        {
            speed=speed-10;
            timer->stop();//停止当前计时器
            timer->start(speed);//设置新的计时器
        }
    }
}
void Snake::IsHit()
{
    for(int i=1;i<vSnakeRect.size();i++)//遍历蛇身
    {
        if(SnakeHead==vSnakeRect[i])//蛇头与蛇身重合
        {
            sDisplay="游戏结束";
            blsOver=true;
            update();
        }
    }
}